Problem s NetApi32.dll na Win 9X! WAS: Jak zjistit informace o aktualnim uzivateli?
Otázka od: Ing. Igor Vodicka
26. 8. 2004 9:15
aktualnim uzivateli?
Podle predesleho sub. jsem provedl nasledujici upravu:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
JclSecurity, StdCtrls, JclSysInfo;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
L_username: TLabel;
L_privilege: TLabel;
ListBox1: TListBox;
Label3: TLabel;
Label4: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
NetLocalGroupGetMembers: function (
servername: PWideChar;
localgroupname: PWideChar;
level: DWORD;
var bufptr: Pointer;
prefmaxlen: DWORD;
var entriesread: DWORD;
var totalentries: DWORD;
var resumehandle: DWORD): Integer; stdcall;
NetUserGetInfo: function (
servername: PWideChar;
localgroupname: PWideChar;
level: DWORD;
var bufptr: Pointer): Integer; stdcall;
NetApiBufferFree: function (buffer: Pointer): Integer; stdcall;
NetApiDllHandle: HWND;
public
{ Public declarations }
end;
type
PLOCALGROUP_MEMBERS_INFO_1 = ^LOCALGROUP_MEMBERS_INFO_1;
LOCALGROUP_MEMBERS_INFO_1 = record
lgrmi1_sid: PSID;
lgrmi1_sidusage: SID_NAME_USE;
lgrmi1_name: LPWSTR;
end;
function GetEnvVar(const Name:String):String;
var
Form1: TForm1;
ListUsers,ListGroups: TStringList;
implementation
{$R *.DFM}
procedure GetLocalGroupUsers(lpwServer, lpwGroup : PWideChar);
type
TUserArray = array of LOCALGROUP_MEMBERS_INFO_1;
var
pBuffer: Pointer;
cbRead,cbTotal,Res,hRes: Cardinal;
i: Integer;
UserName: PWideChar;
begin
hRes := 0;
repeat
Res := Form1.NetLocalGroupGetMembers(lpwServer, lpwGroup, 1, pBuffer,
1024, cbRead, cbTotal, hRes);
if (Res = 0) or (Res = ERROR_MORE_DATA) then
begin
for i := 0 to cbRead-1 do
begin
UserName := TUserArray(pBuffer)[i].lgrmi1_name;
Form1.ListBox1.Items.Add(WideCharToString(lpwGroup)+':'+UserName);
ListUsers.Add(UserName);
ListGroups.Add(WideCharToString(lpwGroup));
end;
Form1.NetApiBufferFree(pBuffer);
end;
until Res<>ERROR_MORE_DATA;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
L_username.Caption := GetEnvVar('USERNAME');
Label3.Caption := GetWindowsVersionString;
case Win32Platform of
VER_PLATFORM_WIN32_WINDOWS: Label4.Caption := 'Win 9X, ME';
VER_PLATFORM_WIN32_NT:
begin
NetApiDllHandle := LoadLibrary(PChar('NETAPI32.DLL'));
if NetApiDllHandle <>0 then
begin
Label4.Caption := 'Win NT, 2K, XP';
@NetLocalGroupGetMembers :=
GetProcAddress(NetApiDllHandle,'NetLocalGroupGetMembers');
@NetApiBufferFree :=
GetProcAddress(NetApiDllHandle,'NetApiBufferFree');
if (@NetLocalGroupGetMembers<>nil) and (@NetApiBufferFree<>nil) then
begin
ListUsers := TStringList.Create;
ListGroups := TStringList.Create;
try
GetLocalGroupUsers('', 'Administrators'); // prazdny retazec je
lokalny stroj
GetLocalGroupUsers('', 'Power Users');
GetLocalGroupUsers('', 'Users');
L_privilege.Caption :=
ListGroups.Strings[ListUsers.IndexOf(L_username.Caption)];
finally
ListUsers.Free;
ListGroups.Free;
end;
end;
end;
end;
end;
end;
function GetEnvVar(const Name:String):String;
var L:Dword;
begin
L:=GetEnvironmentVariable(PChar(Name),nil,0);
SetString(Result,nil,L);
if GetEnvironmentVariable(PChar(Name),PChar(Result),L) <> L-1 then
begin
RaiseLastWin32Error;
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if NetApiDllHandle<>0 then
FreeLibrary(NetApiDllHandle);
end;
end.
Je to jen testovaci programek pro reseni problemu v prechazajicim sub.
> -----Original Message-----
> From: delphi-l-owner@clexpert.cz [mailto:delphi-l-owner@clexpert.cz]On
> Behalf Of Ing. Igor Vodicka
>
> Jinymi slovy, potrebuji pri spusteni programu zjistit (na Win 9X
> test nemusi
> probehnout), ze aktualni uzivatel je minimalne "power users".
> Program totiz
> potrebuje prava pro zapis do slozek v progam files, kde ja nainstalovany.
>
Pokud programek spustim na Win2000 nabo XP vse je OK. Na Win 98 se objevi
hlaska:
Win32 Error. Code 203. System nenalezl zadanou systemovou promennou.
Hlaska se zrejme tyka promenne LOCALGROUP_MEMBERS_INFO_1 a funkce
NetLocalGroupGetMembers, ktere nejsou na Win 9X dostupne.
Existuje nejaky ekvivalent pro Win 9X nebo nevite nekdo jak z toho ven?
Ing. Igor Vodicka
informacni systemy
Nakladatelstvi Sagit
Tel.: 59 6786 001
HTTP://www.sagit.cz/
Odpovedá: Ondrej Kelle
26. 8. 2004 9:39
aktualnim uzivateli?
[snip]
> Pokud programek spustim na Win2000 nabo XP vse je OK. Na Win
> 98 se objevi hlaska:
>
> Win32 Error. Code 203. System nenalezl zadanou systemovou promennou.
Zaujimave, na ktorom riadku sa objavi ta hlaska?
Nemas nahodou este niekde v projekte zabudnute tie staticke deklaracie?
> Hlaska se zrejme tyka promenne LOCALGROUP_MEMBERS_INFO_1 a funkce
> NetLocalGroupGetMembers, ktere nejsou na Win 9X dostupne.
To asi nie. Ten kod v pripade, ze bezi na Windows 9x, netapi32.dll vobec
nepouziva.
HTH
TOndrej
Odpovedá: Ing. Igor Vodicka
26. 8. 2004 10:18
aktualnim uzivateli?
> -----Original Message-----
> From: delphi-l-owner@clexpert.cz [mailto:delphi-l-owner@clexpert.cz]On
> Behalf Of Ondrej Kelle
> > Win32 Error. Code 203. System nenalezl zadanou systemovou promennou.
>
> Zaujimave, na ktorom riadku sa objavi ta hlaska?
Problem trochu je, ze programuji na Win 2000 (zde je vse OK). Programek pak
testuji i na Win 98 a zde je problem.
Udelal jsem si za kazdym radkem vlastni hlasku, ze tuda program projel.
program Project1;
uses
Forms, Dialogs,
Unit1 in 'Unit1.pas' {Form1};
{$R *.RES}
begin
ShowMessage('START');
Application.Initialize;
ShowMessage('Application.Initialize;');
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Obe hlasky se objevily, ale hlasky v CreateForm uz ne, nastala chyba. Jde to
neja otestovat kde to krachne, kdyz na PC s Win 98 nemam Deplhi (delam v D5
ent).
> Nemas nahodou este niekde v projekte zabudnute tie staticke deklaracie?
>
Ne, nejsou tam.
Ing. Igor Vodicka
informacni systemy
Nakladatelstvi Sagit
Tel.: 59 6786 001
HTTP://www.sagit.cz/
Odpovedá: Ondrej Kelle
26. 8. 2004 10:25
aktualnim uzivateli?
>> Win32 Error. Code 203. System nenalezl zadanou systemovou
>> promennou.
Aha, tak som si to precital pozornejsie
203 = ERROR_ENVVAR_NOT_FOUND
to bude ten riadok
L_username.Caption := GetEnvVar('USERNAME');
skratka na tych Windows taka premenna nie je definovana.
Tu si sa na vlastnej kozi presvedcil o tom, ze je lepsie pouzit API funkciu,
ak taka na dany ucel existuje.
GetUserName by mala fungovat vsade rovnako.
HTH
TOndrej
Odpovedá: Ing. Igor Vodicka
26. 8. 2004 12:35
aktualnim uzivateli?
Super, to bylo presne ono. Na zjisteni aktualniho uzivatele jsem nakonec
pouzil funkci GetLocalUserName z JCL a uz je to OK.
Diky
Ing. Igor Vodicka
informacni systemy
Nakladatelstvi Sagit
Tel.: 59 6786 001
HTTP://www.sagit.cz/
> -----Original Message-----
> From: delphi-l-owner@clexpert.cz [mailto:delphi-l-owner@clexpert.cz]On
> Behalf Of Ondrej Kelle
>
> >> Win32 Error. Code 203. System nenalezl zadanou systemovou
> >> promennou.
>
> Aha, tak som si to precital pozornejsie
> 203 = ERROR_ENVVAR_NOT_FOUND
>
> to bude ten riadok
> L_username.Caption := GetEnvVar('USERNAME');
>
> skratka na tych Windows taka premenna nie je definovana.
> Tu si sa na vlastnej kozi presvedcil o tom, ze je lepsie pouzit
> API funkciu,
> ak taka na dany ucel existuje.
>